 #include<msp430G2553.h>
 // 看门狗定时器实现 led闪烁
   void   main( void )
   {
     unsigned int i=0;
     WDTCTL=WDTPW+WDTHOLD;      //关闭看门狗   watch dog control
                                //(看门狗控制寄存器)=（赋值）watch dog password（0×5A00）+ WDTCTL这个寄存器的HOLD位置1 (0×0080)
     P1DIR |=BIT0;              //P1.0为1，输出  红灯
     P1OUT &=~BIT0;             //暗
     for(i=0;i<16000;i++);
  //   for(i=0;i<10;i++);
     P1OUT |=BIT0;             //亮
     WDTCTL= WDT_ARST_1000;    //启动看门狗为1000ms定时
	 // 看门狗发小cpu死循环不响应，会使cpu重启
	 // 就会执行上面的初始化程序 灯会闪烁
   //  WDTCTL= WDT_ARST_250;   // 250ms
     while(1);
   }
/////////////////////////////////////////////////////////////////////////
///////////////////////////////其二//////////////////////
/*设定看门狗定时器工作模式为看门狗，P1.0口接 LED，正常工作时为常亮，由于 看门狗的复位作用，
 * LED  会闪烁。引入“喂狗”后，看门狗不会再复位，LED也不再闪烁。 */

   #include<MSP430G2553.h>
   void   main( void )
   {
     unsigned int i=0;
     WDTCTL=WDTPW+WDTHOLD; //关闭看门狗   watch dog control
                           //(看门狗控制寄存器)=（赋值）
//watch dog password（0×5A00）+ WDTCTL这个寄存器的HOLD位置1 (0×0080)
     P1DIR |=BIT0;
     P1OUT &=~BIT0;                                    //暗
     for(i=0;i<60000;i++);
     P1OUT |=BIT0;                                     //亮
     WDTCTL= WDT_ARST_1000;                             //启动看门狗为1000ms定时
     while(1)
          {
          for(i=0;i<1000;i++); //主函数任务
          WDTCTL = WDT_ARST_1000 + WDTCNTCL; 
		  // 喂狗，且不影响看门狗定时设置  watch   dog   timer   counter   clear 看门狗定时器清零
          // 除了喂狗，还得重新设定看门狗定时值
// 注： “#define   WDT_ARST_1000   (WDTPW+WDTCNTCL+WDTSSEL) ”是将看门狗复位定 时值设为 1s 的宏定义组合
          }
   }
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////其三//////////////////////////////////////////
 // 使用看门狗定时器，低功耗的实现P1.0 所接LED 每秒1 次频率闪烁。
# include    <msp430G2553.h>
   void main(void)
   {
         WDTCTL = WDT_ADLY_1000;                           //定时周期为1000ms
         IE1 |= WDTIE;                                     //使能WDT 中断
         P1DIR |= 0x01;                                    // P1.0输出
          _enable_interrupts();                            //等同_EINT() ， 系统总中断允许
         while(1)                                          //循环等待定时器溢出中断
         {
         _bis_SR_register(LPM3_bits);                       //进入 LPM3
         _NOP();
         }
   }
   //===========看门狗中断服务子程序========
   #pragma vector= WDT_VECTOR
   __interrupt void WDT_ISR (void)                          //此处开头为双下划线
   {
         P1OUT ^= 0x01;                                     //P1.0取反
   }
////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////其四///////////////////////////////////////////////
// 将 RST/NMI  引脚设为NMI 模式，主程序中点亮 P1.0  口LED，在NMI  中断中关掉
// LED。现象为当按下RST 按键时，LED 熄灭，并且再也不亮（除非重新上电）。
   #include<MSP430G2553.h>
   void   main( void )
   {
     WDTCTL = WDTPW + WDTHOLD + WDTNMI;                    //NMI模式（非Reset模式）
      IE1=NMIIE;                                          //开NMI中断，无需开总中断
      P1DIR |=BIT0;                                       //P1.0设为输出口
    //  P1DIR |=BIT6;
      P1OUT |=BIT0;                                       //P1.0 亮灯   RED
    //  P1OUT |=BIT6;
      _bis_SR_register(LPM3_bits);                         //低功耗模式3
   }
   //==========NMI 中断服务子函数==============
   #pragma vector=NMI_VECTOR
   __interrupt void NMI_ISR(void)                          //不可屏蔽中断
   {
	      P1OUT &= ~BIT0;                       //灭灯
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////其五///////////////////////////////////////////////
// 看门狗定时器模式 定时器中断 按键中断检测 led电平翻转
  #include "MSP430G2553.h"
  //-----在main函数前提前声明子函数-----
  void P1_IODect() ;
  void P13_Onclick();
  void GPIO_init();
  void WDT_init();
  void main(void) {
       WDTCTL = WDTPW + WDTHOLD;             //关狗
       GPIO_init();
       WDT_init();
              _enable_interrupts();                      //开总中断
              _bis_SR_register(LPM3_bits);               //LPM3休眠
         }

     //初始化函数GPIO_Init()      由于使用的不是外部中断法检测按键，所以不再配置P1.3 的中断代码。
     /******************************************************************************************************
      *  名  称：GPIO_Init()
      *  功    能：设定按键和LED控制IO的方向，启用按键IO的上拉电阻
      *  入口参数：无
      * 出口参数：无
      *  说    明：无
      *  范  例：无
     ******************************************************************************************************/
     void GPIO_init()
     {
          //-----设定P1.0和P1.6的输出初始值-----
          P1DIR |= BIT0+BIT6;                       //设定P1.0和P1.6为输出
          P1OUT |= BIT0;                            //设定P1.0初值      亮
          P1OUT &= ~BIT6;                           //设定P1.6初值     灭
          //-----配合机械按键，启用内部上拉电阻-----
          P1REN |= BIT3;                           //启用P1.3内部上下拉电阻

          P1OUT |= BIT3;                            //将电阻设置为上拉
          //-----不再使用P1.3中断功能-----
     //   P1DIR &= ~BIT3;                           // P1.3设为输入(可省略)
     //   P1IES |= BIT3;                            // P1.3设为下降沿中断
     //   P1IE  |= BIT3 ;                          // 允许P1.3中断
     }

  //  初始化函数WDT_init()  关于WDT 的初始化，两点说明： 1）一定用宏定义的方法“一气呵成”。  2）对WDTCTL 寄存器的操作，一定不能用“|=”赋值，否则必引发单片机复位。
 /******************************************************************************************************
    *  名  称：W DT_init()
    *  功    能：设定WDT定时中断为16ms，开启WDT定时中断使能
    *  入口参数：无
    * 出口参数：无
    *  说    明：WDT定时中断的时钟源选择ACLK ，可以用LPM3休眠。
    *  范  例：无
   ******************************************************************************************************/
   void WDT_init()
   {
       WDTCTL = WDT_ADLY_16;     //-----设定WDT为16ms中断-----
        IE1 |= WDTIE;            //-----WDT 中断使能-----
   }
 //  中断服务函数WDT_ISR()   WDT定时中断事件发生以后，并不能立刻得出结论是否有按键按下，哪个按键按下。      需要调用事件检测函数P1_IODect() 。
 /******************************************************************************************************
       *  名  称：WDT_ISR()
       *  功   能：响应WDT定时中断服务
       *  入口参数：无
       * 出口参数：无
       *  说    明：WDT定时中断独占中断向量，所以无需进一步判断中断事件，也无需人工清除标志 位。所以，在WDT定时中断服务子函数中，直接调用WDT事件处理函数就可以了。
       *  范  例：无
      ******************************************************************************************************/
      #pragma vector=WDT_VECTOR
      __interrupt void WDT_ISR(void)
      {
          //-----启用Port1事件检测函数-----
          P1_IODect();                             //检测通过，则会调用事件处理函数
      }
// 事件检测函数P1_IODect()  由于改变了检测手段，定时扫描法与中断法按键的事件检测函数的判据当然会不一样。 定时扫描的判据是通过相邻两次检测按键IO  电平来判断的，有以下判断结论：
// 1）前高后高：按键未被按下2）前高后低：按键被按下。 3）前低后低：按键保持按下状态。 4 ）前低后高：按键被松开。
//  为了记录连续两次按键 IO电平，程序中 KEY_Now 必须使用静态局部变量，而  KEY_Past 可以使用局部变量。想明白为什么，就说明初步认识静态局部变量和局部变量的异 同了。
 /******************************************************************************************************
         *  名  称：P1_IODect()
         *  功   能：判断是否有键被按下，哪个键被按下，并调用相应IO的中断事件处理函数
         *  入口参数：无
         * 出口参数：无
         *  说   明：必须用最近两次扫描的结果，才知道按键是否被按下
         *  范  例：无
 ******************************************************************************************************/
        void P1_IODect()
       {
            static unsigned char KEY_Now=0;   //变量值出函数时需保留
            unsigned char KEY_Past=0;
            KEY_Past=KEY_Now;
            //-----查询IO的输入寄存器-----
            if(P1IN&BIT3) KEY_Now=1;
            else            KEY_Now=0;
            //-----前一次高电平、后一次低电平，说明按键按下-----
            if((KEY_Past==1)&&(KEY_Now==0))
                P13_Onclick();
        }
   //事件处理函数P13_Onclick()   本例中的P13_Onclick()事件处理函数与 GPIO  章节的例子里的P13_Onclick()事件处理函 数代码是一样的，
   //因为本来就是用不同方法实现同一功能，功能相同，事件处理函数就该一 样，这也体现了事件函数的代码移植的思想。
 /******************************************************************************************************
         *  名  称：P13_Onclick()
         *  功   能：P1.3的中断事件处理函数，即当P1.3键被按下后，下一步干什么
         *  入口参数：无
         *  出口参数：无
         *  说   明：使用事件处理函数的形式，可以增强代码的移植性和可读性
         *  *  范  例：无

   ******************************************************************************************************/
  void P13_Onclick()             //P1.3 的事件处理函数
  {
      //----翻转IO电平-----
      P1OUT ^= BIT0;
      P1OUT ^= BIT6;
  }



